<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>mybatis</title>
<!-- 2016-06-07 周二 19:19 -->
<meta  http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta  name="generator" content="Org-mode" />
<style type="text/css">
 <!--/*--><![CDATA[/*><!--*/
  .title  { text-align: center; }
  .todo   { font-family: monospace; color: red; }
  .done   { color: green; }
  .tag    { background-color: #eee; font-family: monospace;
            padding: 2px; font-size: 80%; font-weight: normal; }
  .timestamp { color: #bebebe; }
  .timestamp-kwd { color: #5f9ea0; }
  .right  { margin-left: auto; margin-right: 0px;  text-align: right; }
  .left   { margin-left: 0px;  margin-right: auto; text-align: left; }
  .center { margin-left: auto; margin-right: auto; text-align: center; }
  .underline { text-decoration: underline; }
  #postamble p, #preamble p { font-size: 90%; margin: .2em; }
  p.verse { margin-left: 3%; }
  pre {
    border: 1px solid #ccc;
    box-shadow: 3px 3px 3px #eee;
    padding: 8pt;
    font-family: monospace;
    overflow: auto;
    margin: 1.2em;
  }
  pre.src {
    position: relative;
    overflow: visible;
    padding-top: 1.2em;
  }
  pre.src:before {
    display: none;
    position: absolute;
    background-color: white;
    top: -10px;
    right: 10px;
    padding: 3px;
    border: 1px solid black;
  }
  pre.src:hover:before { display: inline;}
  pre.src-sh:before    { content: 'sh'; }
  pre.src-bash:before  { content: 'sh'; }
  pre.src-emacs-lisp:before { content: 'Emacs Lisp'; }
  pre.src-R:before     { content: 'R'; }
  pre.src-perl:before  { content: 'Perl'; }
  pre.src-java:before  { content: 'Java'; }
  pre.src-sql:before   { content: 'SQL'; }

  table { border-collapse:collapse; }
  caption.t-above { caption-side: top; }
  caption.t-bottom { caption-side: bottom; }
  td, th { vertical-align:top;  }
  th.right  { text-align: center;  }
  th.left   { text-align: center;   }
  th.center { text-align: center; }
  td.right  { text-align: right;  }
  td.left   { text-align: left;   }
  td.center { text-align: center; }
  dt { font-weight: bold; }
  .footpara:nth-child(2) { display: inline; }
  .footpara { display: block; }
  .footdef  { margin-bottom: 1em; }
  .figure { padding: 1em; }
  .figure p { text-align: center; }
  .inlinetask {
    padding: 10px;
    border: 2px solid gray;
    margin: 10px;
    background: #ffffcc;
  }
  #org-div-home-and-up
   { text-align: right; font-size: 70%; white-space: nowrap; }
  textarea { overflow-x: auto; }
  .linenr { font-size: smaller }
  .code-highlighted { background-color: #ffff00; }
  .org-info-js_info-navigation { border-style: none; }
  #org-info-js_console-label
    { font-size: 10px; font-weight: bold; white-space: nowrap; }
  .org-info-js_search-highlight
    { background-color: #ffff00; color: #000000; font-weight: bold; }
  /*]]>*/-->
</style>
<script type="text/javascript">
/*
@licstart  The following is the entire license notice for the
JavaScript code in this tag.

Copyright (C) 2012-2013 Free Software Foundation, Inc.

The JavaScript code in this tag is free software: you can
redistribute it and/or modify it under the terms of the GNU
General Public License (GNU GPL) as published by the Free Software
Foundation, either version 3 of the License, or (at your option)
any later version.  The code is distributed WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE.  See the GNU GPL for more details.

As additional permission under GNU GPL version 3 section 7, you
may distribute non-source (e.g., minimized or compacted) forms of
that code without the copy of the GNU GPL normally required by
section 4, provided you include this license notice and a URL
through which recipients can access the Corresponding Source.


@licend  The above is the entire license notice
for the JavaScript code in this tag.
*/
<!--/*--><![CDATA[/*><!--*/
 function CodeHighlightOn(elem, id)
 {
   var target = document.getElementById(id);
   if(null != target) {
     elem.cacheClassElem = elem.className;
     elem.cacheClassTarget = target.className;
     target.className = "code-highlighted";
     elem.className   = "code-highlighted";
   }
 }
 function CodeHighlightOff(elem, id)
 {
   var target = document.getElementById(id);
   if(elem.cacheClassElem)
     elem.className = elem.cacheClassElem;
   if(elem.cacheClassTarget)
     target.className = elem.cacheClassTarget;
 }
/*]]>*///-->
</script>
</head>
<body>
<div id="content">
<h1 class="title">mybatis</h1>
<div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul>
<li><a href="#sec-1">1. mybatis执行流程</a>
<ul>
<li><a href="#sec-1-1">1.1. mybatis配置</a></li>
<li><a href="#sec-1-2">1.2. 通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂</a></li>
<li><a href="#sec-1-3">1.3. 由会话工厂创建sqlSession即会话，操作数据库需要通过sqlSession进行或者通过sqlSession来获取一个Dao动态代理.</a></li>
<li><a href="#sec-1-4">1.4. mybatis底层自定义了Executor执行器接口操作数据库，Executor只是一个接口,mybatis内部定义了多种实现.</a></li>
<li><a href="#sec-1-5">1.5. Executor找出与执行方法对应的MappedStatement对象. mapper.xml文件中一个sql对应一个Mapped Statement对象，sql的id即是Mapped statement的id。</a></li>
<li><a href="#sec-1-6">1.6. 对Mapped Statement中的sql的参数进行映射.映射输入参数映射就是jdbc编程中对preparedStatement设置参数。</a></li>
<li><a href="#sec-1-7">1.7. 将Mapped Statement在执行sql后将输出结果映射至java对象中，输出结果映射过程相当于jdbc编程中对结果的解析处理过程。</a></li>
</ul>
</li>
<li><a href="#sec-2">2. mybatis独立使用,一个DEMO</a>
<ul>
<li><a href="#sec-2-1">2.1. 创建一个POJO</a></li>
<li><a href="#sec-2-2">2.2. 创建一个Mapper</a></li>
<li><a href="#sec-2-3">2.3. 创建一个映射文件</a></li>
<li><a href="#sec-2-4">2.4. 创建一个Mybatis配置文件</a></li>
<li><a href="#sec-2-5">2.5. 体验一下mybatis带来的方便与快捷</a></li>
</ul>
</li>
<li><a href="#sec-3">3. 映射文件mapper.xml语法(重要)</a>
<ul>
<li><a href="#sec-3-1">3.1. 关联mapper.xml文件与mapper接口.</a></li>
<li><a href="#sec-3-2">3.2. 增删改查</a>
<ul>
<li><a href="#sec-3-2-1">3.2.1. &lt;select&gt;标签对应的sql中的select语句</a></li>
<li><a href="#sec-3-2-2">3.2.2. &lt;insert&gt;标签对应于sql中的insert语句</a></li>
<li><a href="#sec-3-2-3">3.2.3. &lt;update&gt;对应于sql中的update语句</a></li>
<li><a href="#sec-3-2-4">3.2.4. &lt;delete&gt;对应于sql中的delete语句</a></li>
</ul>
</li>
<li><a href="#sec-3-3">3.3. 返加类型映射resultMap与resultType</a></li>
<li><a href="#sec-3-4">3.4. 动态构造</a>
<ul>
<li><a href="#sec-3-4-1">3.4.1. if标签</a></li>
<li><a href="#sec-3-4-2">3.4.2. foreach标签</a></li>
<li><a href="#sec-3-4-3">3.4.3. where标签</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#sec-4">4. mybatis与spring整合</a>
<ul>
<li><a href="#sec-4-1">4.1. 普通配置</a></li>
<li><a href="#sec-4-2">4.2. 使用扫描器</a></li>
<li><a href="#sec-4-3">4.3. 自定义分页插件</a></li>
</ul>
</li>
<li><a href="#sec-5">5. 使用生成器</a></li>
<li><a href="#sec-6">6. 参考</a>
<ul>
<li><a href="#sec-6-1">6.1. </a></li>
<li><a href="#sec-6-2">6.2. </a></li>
</ul>
</li>
</ul>
</div>
</div>
<div id="outline-container-sec-1" class="outline-2">
<h2 id="sec-1"><span class="section-number-2">1</span> mybatis执行流程</h2>
<div class="outline-text-2" id="text-1">

<div class="figure">
<p><img src="mybatis.jpg" alt="mybatis.jpg" />
</p>
</div>
</div>
<div id="outline-container-sec-1-1" class="outline-3">
<h3 id="sec-1-1"><span class="section-number-3">1.1</span> mybatis配置</h3>
<div class="outline-text-3" id="text-1-1">
<p>
SqlMapConfig.xml，此文件作为mybatis的全局配置文件，配置了mybatis的运行环境等信息。
</p>

<p>
mapper.xml文件即sql映射文件，文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。
</p>
</div>
</div>

<div id="outline-container-sec-1-2" class="outline-3">
<h3 id="sec-1-2"><span class="section-number-3">1.2</span> 通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂</h3>
</div>

<div id="outline-container-sec-1-3" class="outline-3">
<h3 id="sec-1-3"><span class="section-number-3">1.3</span> 由会话工厂创建sqlSession即会话，操作数据库需要通过sqlSession进行或者通过sqlSession来获取一个Dao动态代理.</h3>
</div>

<div id="outline-container-sec-1-4" class="outline-3">
<h3 id="sec-1-4"><span class="section-number-3">1.4</span> mybatis底层自定义了Executor执行器接口操作数据库，Executor只是一个接口,mybatis内部定义了多种实现.</h3>
</div>

<div id="outline-container-sec-1-5" class="outline-3">
<h3 id="sec-1-5"><span class="section-number-3">1.5</span> Executor找出与执行方法对应的MappedStatement对象. mapper.xml文件中一个sql对应一个Mapped Statement对象，sql的id即是Mapped statement的id。</h3>
</div>

<div id="outline-container-sec-1-6" class="outline-3">
<h3 id="sec-1-6"><span class="section-number-3">1.6</span> 对Mapped Statement中的sql的参数进行映射.映射输入参数映射就是jdbc编程中对preparedStatement设置参数。</h3>
</div>

<div id="outline-container-sec-1-7" class="outline-3">
<h3 id="sec-1-7"><span class="section-number-3">1.7</span> 将Mapped Statement在执行sql后将输出结果映射至java对象中，输出结果映射过程相当于jdbc编程中对结果的解析处理过程。</h3>
</div>
</div>
<div id="outline-container-sec-2" class="outline-2">
<h2 id="sec-2"><span class="section-number-2">2</span> mybatis独立使用,一个DEMO</h2>
<div class="outline-text-2" id="text-2">
<p>
单独使用mybatis一般尊从以下的步骤,在你只要熟悉mybatis,不必完全按照这个顺序来执行,可以任意顺序
</p>
</div>
<div id="outline-container-sec-2-1" class="outline-3">
<h3 id="sec-2-1"><span class="section-number-3">2.1</span> 创建一个POJO</h3>
<div class="outline-text-3" id="text-2-1">
<div class="org-src-container">

<pre class="src src-java">public class User {
    private int id;
    private String name;
    private String password;
    //......省略setter和getter
}
</pre>
</div>
</div>
</div>
<div id="outline-container-sec-2-2" class="outline-3">
<h3 id="sec-2-2"><span class="section-number-3">2.2</span> 创建一个Mapper</h3>
<div class="outline-text-3" id="text-2-2">
<p>
这个文件相当于DAO接口,根据习惯,这个文件的命令采集以下规则:Pojo类名+Mapper,例如上面的Pojo的类名是User,那么这个接口名就是UserMapper.
</p>
<div class="org-src-container">

<pre class="src src-java">public interface UserMapper {
    public void insert(User user);
    public User findUserById(int userId);
    public List&lt;User&gt; findAllUsers();
}
</pre>
</div>
</div>
</div>
<div id="outline-container-sec-2-3" class="outline-3">
<h3 id="sec-2-3"><span class="section-number-3">2.3</span> 创建一个映射文件</h3>
<div class="outline-text-3" id="text-2-3">
<p>
这个文件是我们实际写sql语句的地方,根据习惯,这个文件与上面的Mapper文件同名,且以.xml结尾. 
我们在开发的过程中要严格按照这个命名习惯,这样大家在协作的过程中更加容易定位问题.
</p>
<div class="org-src-container">

<pre class="src src-xml">&lt;mapper namespace="com.idaycrm.leaningmybatis.mapper.UserMapper"&gt;

  &lt;select id="findUserById" resultType="com.idaycrm.leaningmybatis.model.User" &gt; 
    select * from user where id = #{id}
  &lt;/select&gt;

&lt;/mapper&gt;
</pre>
</div>
</div>
</div>
<div id="outline-container-sec-2-4" class="outline-3">
<h3 id="sec-2-4"><span class="section-number-3">2.4</span> 创建一个Mybatis配置文件</h3>
<div class="outline-text-3" id="text-2-4">
<p>
空个文件是把mapper接口和mapper.xml文件进行关联起来的关键所在.
但这个文件格式较统一,我们只要按照下面这个示例稍微修改一下就可以用了.
</p>
<div class="org-src-container">

<pre class="src src-xml">&lt;configuration&gt;
  &lt;environments default="development"&gt;
    &lt;environment id="development"&gt;
      &lt;transactionManager type="JDBC"/&gt;
      &lt;dataSource type="POOLED"&gt;
        &lt;property name="driver" value="com.mysql.jdbc.Driver"/&gt;
      &lt;property name="url" value="jdbc:mysql://172.1.1.6:3306/test1"/&gt;
      &lt;property name="username" value="developer"/&gt;
      &lt;property name="password" value="developer"/&gt;
      &lt;/dataSource&gt;
    &lt;/environment&gt;
  &lt;/environments&gt;

  &lt;!-- 映射文件，mybatis精髓 --&gt;
  &lt;mappers&gt;
    &lt;mapper resource="com/idaycrm/leaningmybatis/mapper/UserMapper.xml"/&gt;
  &lt;/mappers&gt;

&lt;/configuration&gt;
</pre>
</div>
</div>
</div>
<div id="outline-container-sec-2-5" class="outline-3">
<h3 id="sec-2-5"><span class="section-number-3">2.5</span> 体验一下mybatis带来的方便与快捷</h3>
<div class="outline-text-3" id="text-2-5">
<p>
到这里我们已经完成了使用mybatis,现在我们需要写一个测试用例来体验一下:
</p>
<div class="org-src-container">

<pre class="src src-java">public class UserMapperTest {

    @Test
    public void findUserById() {
        SqlSession sqlSession = getSessionFactory().openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = userMapper.findUserById(2);
        Assert.assertNotNull("没找到数据", user);
    }

    private static SqlSessionFactory getSessionFactory() {
        SqlSessionFactory sessionFactory = null;
        String resource = "configuration.xml";
        try {
            sessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader(resource));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sessionFactory;
    }
}
</pre>
</div>
<p>
上面的完整示例代码可以从这里下载:<a href="https://git.oschina.net/longlord/learning-mybatis.git">https://git.oschina.net/longlord/learning-mybatis.git</a>
</p>

<p>
从上面的测试用例中,我们可以看到,我们使用mybatis,一般流程是:
a. 通过mybatis配置文件创建SqlSessionFactory对象
b. 通过SqlSessionFactory创建SqlSession对象.
c. 通过SqlSession创建映射接口
d. 直接使用映射接口中定义的方法来对数据库进行操作.
</p>

<p>
从上面流程中我们可以看到,mybatis帮我们做很大使用JDBC操作数据库里经常重复的代码.
比如打开连接,创建语句,格式化参数等.
我们使用mybatis的话,可以把更多的精力集中在写实现我们的业务需求的sql语句上了.
</p>
</div>
</div>
</div>

<div id="outline-container-sec-3" class="outline-2">
<h2 id="sec-3"><span class="section-number-2">3</span> 映射文件mapper.xml语法(重要)</h2>
<div class="outline-text-2" id="text-3">
<p>
从上面的分析中我们可以看到,我们大部分的时间都会花在写sql语句上,而维护这些sql语句的地方
就是这个mapper.xml文件,所以我们如何编写这个映射文件是mybatis的一个非常重要内容.
</p>
</div>
<div id="outline-container-sec-3-1" class="outline-3">
<h3 id="sec-3-1"><span class="section-number-3">3.1</span> 关联mapper.xml文件与mapper接口.</h3>
<div class="outline-text-3" id="text-3-1">
<p>
每一个mapper.xml文件的根节点是一个&lt;mapper&gt;标签.且每一个mapper.xml文件有且只有一个mapper根节点
这个mapper有一个属性:namespace
这个属性的值必须与需要影响的mapper接口的全名(即包名+类名)一致,否则启动时会报错.
例如:
&lt;mapper namespace="com.idaycrm.leaningmybatis.mapper.UserMapper"&gt;
则说明这个mapper对应的接口是com.idaycrm.leaningmybatis.mapper.UserMapper
</p>

<p>
另外,mapper.xml中&lt;mapper&gt;的标签下面,会有4个常用的标签:
&lt;select&gt;,&lt;update&gt;,&lt;delete&gt;,&lt;insert&gt;
这4个标签分别对应于sql语法中的4个基本操作:增删改查.
这里我们先不管增删改查怎么个写法,这里需要注意的是这4个标签都有一个必写属性:id
例如:
&lt;select id="findUserById" resultType="com.idaycrm.leaningmybatis.model.User" &gt; 
这个id属性是很重要的,他必须与mapper接口中的方法名一致,否则启动时会报错.
</p>
</div>
</div>
<div id="outline-container-sec-3-2" class="outline-3">
<h3 id="sec-3-2"><span class="section-number-3">3.2</span> 增删改查</h3>
<div class="outline-text-3" id="text-3-2">
<p>
上面提到,mapper.xml文件有4个专门的标签分别对应于4种常见的数据库操作.
</p>
</div>
<div id="outline-container-sec-3-2-1" class="outline-4">
<h4 id="sec-3-2-1"><span class="section-number-4">3.2.1</span> &lt;select&gt;标签对应的sql中的select语句</h4>
<div class="outline-text-4" id="text-3-2-1">
<p>
select标签用于把sql语句的结果转化成Pojo对象.
他有一个很重要的属性: resultType
这个属性控制着把返回结果转化成哪个类型的对象,他的类型必须全名(即包名+类名),且必须与Mapper接品中的方法的返回值一致.否则调用时会报错.
我们在这里只需要指定返回哪种类型,mybatis就会魔术般的把结果转化成我们指定的类型.
但是,这个魔术其实并不是很智能啦, 他也只是把数据库字段名与我们的pojo类的成员变量名字相同的对应起来而已.
例如:
我们这里定义的Pojo类,有这个3个成员变量: id,name,password,
而我们的数据库中也恰巧有这3个字段名:id,name,password.
所以能够对应起来,看起来很魔术,但是如果我们数据库中的3个字段名是id,username,password的话
就会有问题,程序代码可以正常执行,但是user对象的name属性将会是空值,这种情况怎么办:
一个简单的解决办法是,修改一下我们的sql:
例如如果我们的sql是如下面的这个例子:
&lt;select id="findUserById" resultType="com.idaycrm.leaningmybatis.model.User" &gt; 
    select id,username,password from user where id = 2
&lt;/select&gt;
则只需改为下面这种型式,即可以解决这个问题.
&lt;select id="findUserById" resultType="com.idaycrm.leaningmybatis.model.User" &gt; 
    select id,username as name,password from user where id = 2
&lt;/select&gt;
从这个例子中,我们可以看到,我们在sql语句中只是写了id=2这样的情况,在实际应用中不可能会有这种情况,
实际开发过种当中更多是我们传入一个id参数来查询相应的数据.
这就涉及一个传入参数与占位符的用法了.
</p>
</div>
<ol class="org-ol"><li><a id="sec-3-2-1-1" name="sec-3-2-1-1"></a>传入参数与占位符<br  /><div class="outline-text-5" id="text-3-2-1-1">
<p>
当我们需要传入的参数只有一个的时候,使用方法很简单
我们只要在sql时而把id=2修改为一个占位符用法id=#{id}
例如上面这个例子:
&lt;select id="findUserById" resultType="com.idaycrm.leaningmybatis.model.User" &gt; 
    select id,username,password from user where id = 2
&lt;/select&gt;
我们需要修改为
&lt;select id="findUserById" resultType="com.idaycrm.leaningmybatis.model.User" &gt; 
    select id,username,password from user where id = #{id}
&lt;/select&gt;
我们便可以在方法中传入一个id的参数来调用这个方法了.实现上当只有一个参数的时候,这个的这个占位符{id}可以写为任何的名字,例如:{abc}
但我们一般是采用和Mapper接口的参数一样的参数名,这样也便于不同的人维护同一份代码.
</p>

<p>
当有多个参数的时候,写法就有些不一样了.
一个例子,如果需要使用一个按用户名和密码来查询的接口的时候.
接口方法定义如下的时候会有一些问题:
</p>
<div class="org-src-container">

<pre class="src src-java">public User findUserByUserNameAndPassword(String name,String password);
</pre>
</div>
<p>
此时如果我们在mapper.xml文件中定义如下的时候会出现一些调用异常的情况,说没有定义#{name},#{password}
</p>
<div class="org-src-container">

<pre class="src src-xml">&lt;select id="findUserById" resultType="com.idaycrm.leaningmybatis.model.User" &gt;
    select id,username,password from user where name=#{name} and password=#{password}
&lt;/select&gt;
</pre>
</div>
<p>
第一个解决办法是修改接口为:
</p>
<div class="org-src-container">

<pre class="src src-java">public User findUserByUserNameAndPassword(Map map);
</pre>
</div>
<p>
然后在调用的时候这么调用:
</p>
<div class="org-src-container">

<pre class="src src-java">Map map = new HashMap();
map.put("name","aaa");
map.put("password","bbb");
findUserByUserNameAndPassword(map);
</pre>
</div>
<p>
这么使用代码比较丑,
所以mybatis为我们提供了另外一种较优雅的方法,这个也是我推荐的方法
需要修改上面的接口为:
</p>
<div class="org-src-container">

<pre class="src src-java">public User findUserByUserNameAndPassword(@Param("name") String name,@Param("password") String password);
</pre>
</div>
<p>
在原理mybatis在调用的时候也是把这两个参数放到了map里头,然后转化为第一种方法的调用方法.
但由于我们采用了注解,代码的可读性提高了不少.
</p>
</div>
</li>

<li><a id="sec-3-2-1-2" name="sec-3-2-1-2"></a>preparedStatment与statment<br  /><div class="outline-text-5" id="text-3-2-1-2">
<p>
另外占位符方面,mybatis除了支持这种写法#{id},还支持${id}
但我们要使用${id}这种语法的时候还需要在select上面加上这个属性statment="STATMENT".
从这个属性我们可以知道,这是控制在使用JDBC时是使用prepareStatment还是Statment的作用的.
默认mybatis是使用prepareStatment的,所以占位符采用这种写法#{id},这也是我们推荐的方法,
可以避免被sql注入攻击.我的建议是: 除非你很清楚自已为什么要使用${id}型式的占位符,并且考虑了各种风险,否则不要使用.
</p>
</div>
</li></ol>
</div>

<div id="outline-container-sec-3-2-2" class="outline-4">
<h4 id="sec-3-2-2"><span class="section-number-4">3.2.2</span> &lt;insert&gt;标签对应于sql中的insert语句</h4>
<div class="outline-text-4" id="text-3-2-2">
<p>
insert语句支持select相同的支持传入参数的方法.
但是在实际开发过程中,我们使用insert时很少采用与select相同的方式来传入参数,
我们更多是使用一个paramterType的属性来定义一个传入的参数的类型,例如:
</p>
<div class="org-src-container">

<pre class="src src-java">public void insert(User user);
</pre>
</div>
<p>
我们需要在xml中定义这个:
</p>
<div class="org-src-container">

<pre class="src src-xml">&lt;insert id="insert" parameterType="com.idaycrm.leaningmybatis.model.User"&gt;
insert into user(id,name,password) values(#{id},#{name},#{password})
&lt;/insert&gt;
</pre>
</div>
<p>
从这个例子可以看出,当我们使用parameterType的时候,占位符#{id}的值获取的是这个Bean的geId(),getName(),getPassword().
只要这个bean中有相应的get的方法,我们就可以使用相应的占位符.
</p>
</div>
</div>
<div id="outline-container-sec-3-2-3" class="outline-4">
<h4 id="sec-3-2-3"><span class="section-number-4">3.2.3</span> &lt;update&gt;对应于sql中的update语句</h4>
<div class="outline-text-4" id="text-3-2-3">
<p>
其用法和上面的insert类似,不细说.
</p>
</div>
</div>
<div id="outline-container-sec-3-2-4" class="outline-4">
<h4 id="sec-3-2-4"><span class="section-number-4">3.2.4</span> &lt;delete&gt;对应于sql中的delete语句</h4>
<div class="outline-text-4" id="text-3-2-4">
<p>
其用法也和上面的insert类似,不细说.
</p>
</div>
</div>
</div>
<div id="outline-container-sec-3-3" class="outline-3">
<h3 id="sec-3-3"><span class="section-number-3">3.3</span> 返加类型映射resultMap与resultType</h3>
<div class="outline-text-3" id="text-3-3">
<p>
上面我们提到,如果我们返回的字段名与Bean中的字段名不一致的时候,我们可以使用sql中的as语法来做映射.
但是当很多个参数不一致的时候,我们这种做法就显得很低效,为此,mybatis还支持一个resultMap的属性.
要使用这个属性首先需要在mapper.xml文件中定义一个resultMap的标签内容,例如:
</p>
<div class="org-src-container">

<pre class="src src-xml">&lt;mapper namespace="com.idaycrm.leaningmybatis.mapper.UserMapper"&gt;
  &lt;resultMap id="BaseResultMap" type="com.idaycrm.leaningmybatis.model.User"&gt;
    &lt;id column="id"  property="id" /&gt;
    &lt;result column="username" property="name" /&gt;
    &lt;result column="password" property="password" /&gt;
  &lt;/resultMap&gt;

  &lt;select id="findUserById" resultMap="BaseResultMap" &gt; 
    select * from user where id = #{cd}
  &lt;/select&gt;
&lt;/mapper&gt;
</pre>
</div>
<p>
这样我们就可以使用自动映射了
</p>
</div>
</div>
<div id="outline-container-sec-3-4" class="outline-3">
<h3 id="sec-3-4"><span class="section-number-3">3.4</span> 动态构造</h3>
<div class="outline-text-3" id="text-3-4">
<p>
这个也是mybatis迷人的一个功能,这里我们只介绍只个常用的标签,更多内容大家在实际开发中遇到的话,可以上mybatis的官网进行查阅.
</p>
</div>
<div id="outline-container-sec-3-4-1" class="outline-4">
<h4 id="sec-3-4-1"><span class="section-number-4">3.4.1</span> if标签</h4>
<div class="outline-text-4" id="text-3-4-1">
<p>
if用于决定是否需要加入相应的条件
例如:
</p>
<div class="org-src-container">

<pre class="src src-xml">&lt;mapper namespace="com.idaycrm.leaningmybatis.mapper.UserMapper"&gt;
  &lt;select id="findUserByUserNameAndPassword" resultMap="BaseResultMap" &gt; 
    select * from user where name = #{name} 
    &lt;if test="password!=null and password!=''"&gt;
      password=#{password}
    &lt;/if&gt;
  &lt;/select&gt;
&lt;/mapper&gt;
</pre>
</div>
</div>
</div>

<div id="outline-container-sec-3-4-2" class="outline-4">
<h4 id="sec-3-4-2"><span class="section-number-4">3.4.2</span> foreach标签</h4>
<div class="outline-text-4" id="text-3-4-2">
<p>
这个主要应用在于构造一个In条件.
例如:
</p>
<div class="org-src-container">

<pre class="src src-java">public List&lt;User&gt; findUsers(List&lt;Integer&gt; ids);
</pre>
</div>

<div class="org-src-container">

<pre class="src src-xml">&lt;mapper namespace="com.idaycrm.leaningmybatis.mapper.UserMapper"&gt;
  &lt;select id="findUsers" resultMap="BaseResultMap" &gt; 
    select * from user
    where id in 
    &lt;foreach collection="list" index="index" item="tag" open="("
    separator="," close=")"&gt;
      #{tag}
    &lt;/foreach&gt;
  &lt;/select&gt;
&lt;/mapper&gt;
</pre>
</div>
<p>
还可以用于构造批量插入的语句
</p>
</div>
</div>

<div id="outline-container-sec-3-4-3" class="outline-4">
<h4 id="sec-3-4-3"><span class="section-number-4">3.4.3</span> where标签</h4>
<div class="outline-text-4" id="text-3-4-3">
<p>
使用where标签一般和if标签匹配使用,好处是,他能自动去掉第一个and.
例如:
</p>
<div class="org-src-container">

<pre class="src src-xml">&lt;mapper namespace="com.idaycrm.leaningmybatis.mapper.UserMapper"&gt;
  &lt;select id="findUsers" resultMap="BaseResultMap" &gt; 
    select * from user
    &lt;where&gt;
      &lt;if test="name!=null and name!=''"&gt;
        name = #{name}
      &lt;/if&gt;
      &lt;if test="password!=null and password!=''"&gt;
        and password = #{password}
      &lt;/if&gt;
    &lt;/where&gt;
  &lt;/select&gt;
&lt;/mapper&gt;
</pre>
</div>
</div>
</div>
</div>
</div>

<div id="outline-container-sec-4" class="outline-2">
<h2 id="sec-4"><span class="section-number-2">4</span> mybatis与spring整合</h2>
<div class="outline-text-2" id="text-4">
</div><div id="outline-container-sec-4-1" class="outline-3">
<h3 id="sec-4-1"><span class="section-number-3">4.1</span> 普通配置</h3>
<div class="outline-text-3" id="text-4-1">
<p>
回顾我们刚才使用mybatis的过程.我们是从构造SqlSessionFactory开始的,所以第一步就是配置这个对像
</p>

<div class="org-src-container">

<pre class="src src-xml">&lt;bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"&gt;
  &lt;property name="dataSource" ref="dataSource" /&gt;
  &lt;!-- 自动扫描entity目录, 省掉Configuration.xml里的手工配置 --&gt;
  &lt;property name="mapperLocations" value="classpath:com/idaycrm/leaningmybatis/mapper/*.xml" /&gt;
&lt;/bean&gt;

&lt;!--  手动注册 --&gt;
&lt;bean id="existNewsMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"&gt;
  &lt;property name="mapperInterface" value="com.idaycrm.leaningmybatis.mapper.UserMapper" /&gt;
  &lt;property name="sqlSessionFactory" ref="sqlSessionFactory" /&gt;
&lt;/bean&gt;

&lt;bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"&gt;
  &lt;property name="dataSource" ref="dataSource" /&gt;
&lt;/bean&gt;
</pre>
</div>
<p>
这里特别需要注意的这个属性mapperLocations,他是支持通配符的.
</p>
</div>
</div>

<div id="outline-container-sec-4-2" class="outline-3">
<h3 id="sec-4-2"><span class="section-number-3">4.2</span> 使用扫描器</h3>
<div class="outline-text-3" id="text-4-2">
<div class="org-src-container">

<pre class="src src-xml">&lt;bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"&gt;
  &lt;property name="dataSource" ref="dataSource" /&gt;
  &lt;!-- 自动扫描entity目录, 省掉Configuration.xml里的手工配置 --&gt;
  &lt;property name="mapperLocations" value="classpath:com/idaycrm/leaningmybatis/mapper/*.xml" /&gt;
&lt;/bean&gt;

&lt;!-- 自动扫描 --&gt;
&lt;bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"&gt;
  &lt;property name="basePackage" value="org.mybatis.spring.mapper" /&gt;
  &lt;property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" /&gt;
&lt;/bean&gt;

&lt;bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"&gt;
  &lt;property name="dataSource" ref="dataSource" /&gt;
&lt;/bean&gt;
</pre>
</div>
<p>
这里需要注意的是basePackage属性也支持通配符的,例如可以这么使用:com.zingrow.**.mapper
</p>
</div>
</div>

<div id="outline-container-sec-4-3" class="outline-3">
<h3 id="sec-4-3"><span class="section-number-3">4.3</span> 自定义分页插件</h3>
<div class="outline-text-3" id="text-4-3">
<p>
mybatis还支持写插件,只要类实现这个接口就可以定义为mybatis的插件:
org.apache.ibatis.plugin.Interceptor
</p>

<p>
例如下面的这个pagePlugin可以是任意的实现org.apache.ibatis.plugin.Interceptor.
</p>
<div class="org-src-container">

<pre class="src src-xml">&lt;bean id="pagePlugin" class="someClass"/&gt;

&lt;bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"&gt;
  &lt;property name="dataSource" ref="dataSource" /&gt;
  &lt;!-- 自动扫描entity目录, 省掉Configuration.xml里的手工配置 --&gt;
  &lt;property name="mapperLocations" value="classpath:com/idaycrm/leaningmybatis/mapper/*.xml" /&gt;
  &lt;property name="configurationProperties"&gt;
    &lt;props&gt;
      &lt;prop key="dialect"&gt;mysql&lt;/prop&gt;
    &lt;/props&gt;
  &lt;/property&gt;

  &lt;property name="plugins"&gt;
    &lt;array&gt;
      &lt;ref bean="pagePlugin" /&gt;
    &lt;/array&gt;
  &lt;/property&gt;
&lt;/bean&gt;

&lt;!-- 自动扫描 --&gt;
&lt;bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"&gt;
  &lt;property name="basePackage" value="org.mybatis.spring.mapper" /&gt;
  &lt;property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" /&gt;
&lt;/bean&gt;

&lt;bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"&gt;
  &lt;property name="dataSource" ref="dataSource" /&gt;
&lt;/bean&gt;
</pre>
</div>
<p>
在实际开发过程中,我们会经常使用到分页的功能,为此我们会实现一个分页插件.你们以后在实际开发过种中遇到的知道有这么一回事就可以了.
说到分页,mybatis本身还支持RowBounds类型的分页插件,但是性能很差,我们在实际开发过程中不要使用.
</p>
</div>
</div>
</div>

<div id="outline-container-sec-5" class="outline-2">
<h2 id="sec-5"><span class="section-number-2">5</span> 使用生成器</h2>
<div class="outline-text-2" id="text-5">
<p>
这个不是mybatis本身的功能,是官方出品的一个小工具,在这里我觉得有必要提一下,
他可以用于简单我们开发流程,如何使用这个工具已经超出了本次培训的范围.
感兴起的同学可以参数这个文章: <a href="http://blog.csdn.net/wyc_cs/article/details/9023117">http://blog.csdn.net/wyc_cs/article/details/9023117</a>
学习起来也很容易的.
</p>
</div>
</div>

<div id="outline-container-sec-6" class="outline-2">
<h2 id="sec-6"><span class="section-number-2">6</span> 参考</h2>
<div class="outline-text-2" id="text-6">
</div><div id="outline-container-sec-6-1" class="outline-3">
<h3 id="sec-6-1"><span class="section-number-3">6.1</span> <a href="http://doc.okbase.net/dongying/archive/116783.html">http://doc.okbase.net/dongying/archive/116783.html</a></h3>
</div>
<div id="outline-container-sec-6-2" class="outline-3">
<h3 id="sec-6-2"><span class="section-number-3">6.2</span> <a href="http://www.mybatis.org/spring/zh/factorybean.html">http://www.mybatis.org/spring/zh/factorybean.html</a></h3>
</div>
</div>
</div>
<div id="postamble" class="status">
<p class="date">Created: 2016-06-07 周二 19:19</p>
<p class="creator"><a href="http://www.gnu.org/software/emacs/">Emacs</a> 24.4.1 (<a href="http://orgmode.org">Org</a> mode 8.2.10)</p>
<p class="validation"><a href="http://validator.w3.org/check?uri=referer">Validate</a></p>
</div>
</body>
</html>
